/**
 *
 */
package com.honeybees.framework.common.util.browser;

import org.apache.commons.lang3.StringUtils;

/**
 * <dl>
 * <dt><b> 根据浏览器 User-Agent 判断浏览器、操作平台 </b></dt>
 * <p>
 * <dd>功能描述</dd>
 * </dl>
 * <p>
 * Copyright (C) All rights reserved.
 * </p>
 *
 * @author 李远明
 * @since 2016年4月26日 上午11:00:28
 */
public class UserAgentUtil {

    /**
     * <dl>
     * <dt><b> 根据浏览器 User-Agent 判断浏览器、操作平台 </b></dt>
     * <p>
     * <dd>判断的先后次序：</dd>
     * <dd>根据设备的用户使用量降序排列，这样对于大多数用户来说可以少判断几次即可拿到结果：</dd>
     * <dd>>>操作系统： Windows > 苹果 > 安卓 > Linux > …</dd>
     * <dd>>>浏览器： Chrome > Firefox > IE > …</dd>
     * </dl>
     *
     * @param userAgent 浏览器 navigator.userAgent，形如
     *                  "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36"
     * @return
     * @author 李远明
     * @version 2016年4月26日 上午11:11:46
     */
    public static UserAgent parseUserAgent(String userAgent) {
        if (StringUtils.isBlank(userAgent)) {
            return null;
        }

        if (userAgent.contains("Windows")) { // 主流应用靠前
            /**
             * <pre>
             * ******************
             * 台式机 Windows 系列
             * ******************
             * Windows NT 6.3   -   Windows 8.1
             * Windows NT 6.2   -   Windows 8
             * Windows NT 6.1   -   Windows 7
             * Windows NT 6.0   -   Windows Vista
             * Windows NT 5.2   -   Windows Server 2003; Windows XP x64 Edition
             * Windows NT 5.1   -   Windows XP
             * Windows NT 5.01  -   Windows 2000, Service Pack 1 (SP1)
             * Windows NT 5.0   -   Windows 2000
             * Windows NT 4.0   -   Microsoft Windows NT 4.0
             * Windows 98; Win 9x 4.90  -   Windows Millennium Edition (Windows Me)
             * Windows 98   -   Windows 98
             * Windows 95   -   Windows 95
             * Windows CE   -   Windows CE
             * 判断依据：http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
             * </pre>
             */
            if (userAgent.contains("Windows NT 6.3")) { // // Windows 8.1
                return judgeBrowser(userAgent, "Windows 8.1", "6.3"); // 判断浏览器
            } else if (userAgent.contains("Windows NT 6.2")) { // Windows 8
                return judgeBrowser(userAgent, "Windows 8", "6.2"); // 判断浏览器
            } else if (userAgent.contains("Windows NT 6.1")) { // Windows 7
                return judgeBrowser(userAgent, "Windows 7", "6.1");
            } else if (userAgent.contains("Windows NT 6.0")) { // Windows Vista
                return judgeBrowser(userAgent, "Windows Vista", "6.0");
            } else if (userAgent.contains("Windows NT 5.2")) { // Windows XP x64 Edition
                return judgeBrowser(userAgent, "Windows XP", "5.2 x64 Edition");
            } else if (userAgent.contains("Windows NT 5.1")) { // Windows XP
                return judgeBrowser(userAgent, "Windows XP", "5.1");
            } else if (userAgent.contains("Windows NT 5.01")) { // Windows 2000 Service Pack 1 (SP1)
                return judgeBrowser(userAgent, "Windows 2000", "SP1");
            } else if (userAgent.contains("Windows NT 5.0")) { // Windows 2000
                return judgeBrowser(userAgent, "Windows 2000", "5.0");
            } else if (userAgent.contains("Windows NT 4.0")) { // Microsoft Windows NT 4.0
                return judgeBrowser(userAgent, "Windows NT 4.0", null);
            } else if (userAgent.contains("Windows 98; Win 9x 4.90")) {
                // Windows Millennium Edition (Windows Me)
                return judgeBrowser(userAgent, "Windows ME", null);
            } else if (userAgent.contains("Windows 98")) { // Windows 98
                return judgeBrowser(userAgent, "Windows 98", null);
            } else if (userAgent.contains("Windows 95")) { // Windows 95
                return judgeBrowser(userAgent, "Windows 95", null);
            } else if (userAgent.contains("Windows CE")) { // Windows CE
                return judgeBrowser(userAgent, "Windows CE", null);
            }
        } else if (userAgent.contains("Mac OS X")) {
            /**
             * <pre>
             * ********
             * 苹果系列
             * ********
             * iPod -       Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5
             * iPad -       Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10
             * iPad2    -       Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3
             * iPhone 4 -   Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
             * iPhone 5 -   Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
             * 判断依据：http://www.useragentstring.com/pages/Safari/
             * 参考：http://stackoverflow.com/questions/7825873/what-is-the-ios-5-0-user-agent-string
             * 参考：http://stackoverflow.com/questions/3105555/what-is-the-iphone-4-user-agent
             * </pre>
             */
            // iPhone："Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46
            // (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
            // iPad："Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like
            // Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
            if (userAgent.contains("iPod")) {
                return judgeBrowser(userAgent, "iPod", null); // 判断浏览器
            }
        }
        return null;
    }

    /**
     * <dl>
     * <dt><b> 根据浏览器 User-Agent 判断浏览器、操作平台 </b></dt>
     * <p>
     * <dd>判断的先后次序：</dd>
     * <dd>根据设备的用户使用量降序排列，这样对于大多数用户来说可以少判断几次即可拿到结果：</dd>
     * <dd>>>操作系统： Windows > 苹果 > 安卓 > Linux > …</dd>
     * <dd>>>浏览器： Chrome > Firefox > IE > …</dd>
     * </dl>
     *
     * @param userAgent 浏览器 navigator.userAgent
     * @param osName    系统名称
     * @param osVersion 系统版本
     * @return
     * @author 李远明
     * @version 2016年4月26日 下午2:51:17
     */
    private static UserAgent judgeBrowser(String userAgent, String osName, String osVersion) {
        if (userAgent.contains("Chrome")) {
            /**
             * <pre>
             * ***********
             * Chrome 系列
             * ***********
             * Chrome 24.0.1295.0   -   Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.15 (KHTML, like Gecko) Chrome/24.0.1295.0 Safari/537.15
             * Chrome 24.0.1292.0   -   Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.14 (KHTML, like Gecko) Chrome/24.0.1292.0 Safari/537.14
             * Chrome 24.0.1290.1   -   Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.13 (KHTML, like Gecko) Chrome/24.0.1290.1 Safari/537.13
             * 判断依据：http://www.useragentstring.com/pages/Chrome/
             * </pre>
             */
            String temp = userAgent.substring(userAgent.indexOf("Chrome/") + 7);
            String chromeVersion = null;
            int idx = temp.indexOf(" ");
            if (idx < 0) { // temp形如"24.0.1295.0"
                chromeVersion = temp;
            } else { // temp形如"24.0.1295.0 Safari/537.15"
                chromeVersion = temp.substring(0, idx);
            }
            return new UserAgent("Chrome", chromeVersion, osName, osVersion);
        } else if (userAgent.contains("Firefox")) {
            /**
             * <pre>
             * *******
             * Firefox 系列
             * *******
             * Firefox 16.0.1   -   Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1
             * Firefox 15.0a2   -   Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2
             * Firefox 15.0.2   -   Mozilla/5.0 (Windows NT 6.2; WOW64; rv:15.0) Gecko/20120910144328 Firefox/15.0.2
             * 判断依据：http://www.useragentstring.com/pages/Firefox/
             * </pre>
             */
            String temp = userAgent.substring(userAgent.indexOf("Firefox/") + 8);
            String ffVersion = null;
            int idx = temp.indexOf(" ");
            if (idx < 0) { // temp形如"16.0.1"
                ffVersion = temp;
            } else { // temp形如"16.0.1 Gecko/20121011"
                ffVersion = temp.substring(0, idx);
            }
            return new UserAgent("Firefox", ffVersion, osName, osVersion);
        } else if (userAgent.contains("MSIE")) {
            /**
             * <pre>
             * *******
             * IE 系列
             * *******
             * MSIE 10.0    -   Internet Explorer 10
             * MSIE 9.0 -   Internet Explorer 9
             * MSIE 8.0 -   Internet Explorer 8 or IE8 Compatibility View/Browser Mode
             * MSIE 7.0 -   Windows Internet Explorer 7 or IE7 Compatibility View/Browser Mode
             * MSIE 6.0 -   Microsoft Internet Explorer 6
             * 判断依据：http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
             * </pre>
             */
            if (userAgent.contains("MSIE 10.0")) {// Internet Explorer 10
                return new UserAgent("Internet Explorer", "10", osName, osVersion);
            } else if (userAgent.contains("MSIE 9.0")) {// Internet Explorer 9
                return new UserAgent("Internet Explorer", "9", osName, osVersion);
            } else if (userAgent.contains("MSIE 8.0")) {// Internet Explorer 8
                return new UserAgent("Internet Explorer", "8", osName, osVersion);
            } else if (userAgent.contains("MSIE 7.0")) {// Internet Explorer 7
                return new UserAgent("Internet Explorer", "7", osName, osVersion);
            } else if (userAgent.contains("MSIE 6.0")) {// Internet Explorer 6
                return new UserAgent("Internet Explorer", "6", osName, osVersion);
            }
        } else if (userAgent.contains("Trident") && userAgent.contains("rv")) {
            // Internet Explorer 11
            // "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET
            // CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; rv:11.0) like Gecko"
            int index1 = userAgent.indexOf("rv:");
            int index2 = userAgent.lastIndexOf(')');
            String version = userAgent.substring(index1 + 3, index2);
            return new UserAgent("Internet Explorer", version, osName, osVersion);
        } else { // 暂时支持以上三个主流.其它浏览器,待续...
            return new UserAgent(null, null, osName, osVersion);
        }
        return null;
    }

    public static void main(String[] args) {
        String chromeUserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36";
        UserAgent userAgent1 = parseUserAgent(chromeUserAgent);
        System.out.println(userAgent1);

        String firefoxUserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0";
        UserAgent userAgent2 = parseUserAgent(firefoxUserAgent);
        System.out.println(userAgent2);

        String ie11UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; rv:11.0) like Gecko";
        UserAgent userAgent3 = parseUserAgent(ie11UserAgent);
        System.out.println(userAgent3);

        // int index1 = ie11UserAgent.indexOf("rv:");
        // int index2 = ie11UserAgent.lastIndexOf(')');
        // String version = ie11UserAgent.substring(index1 + 3, index2);
        // System.out.println("version: " + version);

        String ie10UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
        UserAgent userAgent4 = parseUserAgent(ie10UserAgent);
        System.out.println(userAgent4);

        // Properties properties = System.getProperties();
        // Set<Object> keySet = properties.keySet();
        // for (Object object : keySet) {
        // String property = properties.getProperty(object.toString());
        // System.out.println(object + " = " + property);
        // }
    }

}
